package com.scalar.chiptrack.adaptor.miradia.tsmc;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.tsmc.TSMCAdaptor;
import com.scalar.chiptrack.adaptor.tsmc.TSMCLotStatus;
import com.scalar.chiptrack.adaptor.tsmc.TSMCShippingInfo;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.NewAdaptorDAO;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * User: ChandraSekhar
 * Date: Feb 13, 2008
 * Time: 7:18:59 PM
 */
public class TSMCDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;
    private HashMap m_tsmcWipDataMap        = new HashMap();
    private HashMap m_tsmcShipDataMap       = new HashMap();

    public TSMCDataParser() throws ScalarException
    {
        try
        {    m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_TSMC, WIP_TYPE_FAB );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );

            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_TSMC );
            FabSortAdaptorDAO.setLogger( m_parserLogger );
            ShippedLotDAO.setLogger( m_parserLogger );
        }
        catch ( ScalarException se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading TSMC WIP output directory details from database, Exception: " + se );
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new TSMCDataParser().execute();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     *
     */
    public void execute() throws Exception
    {
        printVersionInfo();

        File doneDestDir = new File(  m_dataOutputDir + "/done" );

        File sourceDataoutDir = new File( m_dataOutputDir );

        File[] fileList = sourceDataoutDir.listFiles();
        if ( ( fileList == null ) || ( fileList.length <= 3 ) )
        {
            log( "No file found in directory: " + sourceDataoutDir );
            throw new ScalarException( "\n+-----------No file found in directory " + sourceDataoutDir );
        }

        ArrayList tsmcWipList     = null;
        ArrayList tsmcShipList    = null;
        ArrayList successFileList   = new ArrayList();
        boolean success             = true;

        try
        {
            for ( int i = 0; i < fileList.length; i++ )
            {
                if ( fileList[i].isDirectory() == true )
                {
                    continue;
                }

               if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( TSMCAdaptor.REAL_WIP_INFO_FILE_NAME ) ) )
                {
                    try
                    {
                       tsmcWipList = parseWipInfo( fileList[i].getAbsolutePath() );
                        if ( tsmcWipList != null )
                        {
                            getTSMCWipList( tsmcWipList );
                        }
                        successFileList.add( fileList[i] );
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }
                if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( TSMCAdaptor.SHIPPING_FILE_NAME ) ) )
                {
                    try
                    {
                        tsmcShipList = parseShippingInfo( fileList[i].getAbsolutePath() );
                        if ( tsmcShipList != null )
                        {
                            getTSMCShipList( tsmcShipList );
                        }

                        successFileList.add( fileList[i] );
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
            e.printStackTrace();
            throw e;
        }
        // to save the Fab lot tables
        try
        {
            if ( m_tsmcWipDataMap.isEmpty() == false )
            {
                ArrayList tsmcFabList = new ArrayList();
                tsmcFabList.addAll( m_tsmcWipDataMap.values() );

                log( "Updating Fab Lot Information" );
                FabSortAdaptorDAO.saveFabLot( null, m_tsmcWipDataMap.values().iterator(),WIP_TYPE_FAB, VENDOR_NAME_TSMC );
            }
            else
            {
                System.out.println( "This is FAB Data Parser FAB Part Number List is empty" );
                FabSortAdaptorDAO.closeFabSortLot( null, WIP_TYPE_FAB, VENDOR_NAME_TSMC );
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update Fab Data information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        try
        {
            // Save shipping info -
            if ( m_tsmcShipDataMap.isEmpty() == false )
            {
                log( "Updating shipment Information" );
                ShippedLotDAO.saveShippedLot( null, m_tsmcShipDataMap.values().iterator() );
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update TSMC Shipping information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_TSMC, true, true, true );

        // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_TSMC );

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( TSMCAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TSMCAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TSMCAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
        // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    }//end of execute method

    /**
    * @param wipdataList
    */
    public void getTSMCWipList( ArrayList wipdataList ) throws Exception
    {
        TSMCLotStatus tsmcWipReport = null;
        String partNumber       = null;
        String lotNumber        = null;
        FabSortLot fabSortLot   = null;

        try
        {
            Iterator iterator = wipdataList.iterator();
            while ( iterator.hasNext() )
            {
                tsmcWipReport = ( TSMCLotStatus ) iterator.next();

                if ( tsmcWipReport != null &&  "SHIPPED".trim().equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) == false  )
                {
                    partNumber = tsmcWipReport.getCustomerProduct();
                    lotNumber  = tsmcWipReport.getTsmcLotID();

                    int fabProcessStepId = NewAdaptorDAO.getProcessStepId( partNumber, WIP_TYPE_FAB, WIP_TYPE_FAB );

                    String psType        = null;

                    if ( fabProcessStepId > 0 )
                    {
                        psType = WIP_TYPE_FAB;
                    }
                    else if ("WF1_BOND".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) )
                    {
                        psType = "FAB-BONDING";
                    }
                    else if ("WF1_THIN".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) )
                    {
                        psType = "FAB-CLEN1";
                    }
                    else if ("BVA1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "BVA1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "BVA1_DP".equalsIgnoreCase( tsmcWipReport.getCurrentStage() )
                             || "BWCW1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "BWCW1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "PMR1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() )
                             || "PMR1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "HREL1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "HREL1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() )
                             || "SED1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "SED1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "BPAD1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() )
                             || "BPAD1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) )
                    {
                        psType = "Fab-MemI";
                    }
                    else if ("MIR1_SPU".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "MREL1_PH".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "MREL1_ET".equalsIgnoreCase( tsmcWipReport.getCurrentStage() )
                             || "WAT1_1".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "QC1_INSP".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) || "FINISH1WF".equalsIgnoreCase( tsmcWipReport.getCurrentStage() ) )
                    {
                        psType = "Fab-MemII";
                    }
                    else
                    {
                        psType = WIP_TYPE_FAB;
                    }
                    
                    fabSortLot = ( FabSortLot ) m_tsmcWipDataMap.get( partNumber + lotNumber + psType );
                    if ( fabSortLot == null )
                    {
                        fabSortLot = new FabSortLot(VENDOR_NAME_TSMC, psType );
                        m_tsmcWipDataMap.put( partNumber + lotNumber + psType , fabSortLot );
                    }
                    int quantity = 0;
                    if ( fabSortLot.getQtyIn() != null )
                    {
                        try
                        {
                            quantity = Integer.parseInt( fabSortLot.getQtyIn() );
                        }
                        catch ( NumberFormatException ignore )
                        {
                        }
                        try
                        {
                            quantity += Integer.parseInt( tsmcWipReport.getWaferQty() );
                        }
                        catch ( NumberFormatException ignore )
                        {
                        }
                    }
                    else
                    {
                        try
                        {
                            quantity = Integer.parseInt( tsmcWipReport.getWaferQty() );
                        }
                        catch ( NumberFormatException ignore )
                        {
                        }
                    }

                    fabSortLot.setLotId( lotNumber );
                    fabSortLot.setCustProduct( partNumber );
                    fabSortLot.setDateIn( StringUtils.formatDate( tsmcWipReport.getWaferStartDate(), "MM/dd/yyyy", "MM/dd/yyyy" ) );
                    fabSortLot.setQtyIn( quantity +"");
                    fabSortLot.setStage( tsmcWipReport.getCurrentStage() );
                    fabSortLot.setWaferID( tsmcWipReport.getWaferID() );
                    fabSortLot.setFabLotNumber(lotNumber);
                    fabSortLot.setFabId ( tsmcWipReport.getWaferFab() );
                    fabSortLot.setWsQty ( tsmcWipReport.getWaferStartQty() );
                    if ( "HELD".equalsIgnoreCase( tsmcWipReport.getHoldFlag() ) )
                    {
                        fabSortLot.setLotStatus( LOT_STATUS_HOLD );
                    }
                    else
                    {
                        fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                    }
                }
            }
        }
        catch(Exception e)
        {
            System.out.println(" Error while parsing the real time wip status " + e);
            e.printStackTrace();
        }
    }

    /**
    * Reads, parses the file and saves into database
    */
    private  ArrayList parseWipInfo( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList statusList    = new ArrayList();
        String line             = null;

        try
        {
            File wipInfoFile = new File( fileName );
            if ( wipInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "Parsing the file for WIP Status Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "Parsing the file for WIP Status Report..." );

            BufferedReader reader = new BufferedReader( new FileReader( fileName ) );

            reader.readLine();  // skip 1st line
            reader.readLine();  // skip 2nd line

            while ( ( line = reader.readLine() ) != null )
            {
                TSMCLotStatus wipInfo = new TSMCLotStatus();

                line = line.replaceAll( "\"", "" );

                String[] token = line.split(",");

                for (int x = 0; x < token.length; x++)
                {
                    if (token[x] != null && token[x].trim().length() > 0)
                    {
                        switch (x)
                        {
                            case 0:
                                wipInfo.setCustomerProduct(token[x].trim());
                                break;
                            case 1:
                                wipInfo.setCurrentMfgPart(token[x].trim());
                                break;
                            case 2:
                                wipInfo.setTsmcLotID(token[x].trim());
                                break;
                            case 3:
                                wipInfo.setWaferFab(token[x].trim());
                                break;
                            case 4:
                                wipInfo.setWaferStartQty(token[x].trim());
                                break;
                            case 5:
                                wipInfo.setWaferStartDate(token[x].trim());
                                break;
                            case 6:
                                wipInfo.setCurrentStage(token[x].trim());
                                break;
                            case 7:
                                wipInfo.setWaferQty(token[x].trim());
                                break;
                            case 8:
                                wipInfo.setDieQty(token[x].trim());
                                break;
                            case 9:
                                wipInfo.setHoldFlag(token[x].trim());
                                break;
                            case 10:
                                wipInfo.setUpdateMode(token[x].trim());
                                break;
                            case 11:
                                wipInfo.setCustomerLotID(token[x].trim());
                                break;
                            case 12:
                                wipInfo.setPmFactFlow(token[x].trim());
                                break;
                            case 13:
                                wipInfo.setBackUpFab(token[x].trim());
                                break;
                            case 14:
                                wipInfo.setWaferID(token[x].trim());
                                break;
                        }
                    }
                }
                if ( wipInfo.getCustomerProduct() != null && wipInfo.getCustomerProduct().length() > 0 &&
                     wipInfo.getTsmcLotID() != null && wipInfo.getTsmcLotID().length() > 0 )
                {
                    statusList.add( wipInfo );
                }
            }

            try
            {
                if ( reader != null )
                {
                   reader.close();
                }
            }
            catch(IOException ignore)
            {

            }

        }
        catch (Exception e)
        {
            System.out.println("Exception while parsing Wip Info: " + e);
            System.out.println("Line: " + line);
            throw new ScalarException("Exception while parsing Wip Info: " + e + "\nLine: " + line, e);
        }

        return statusList;
    }

    /**
     * Reads, parses the file and saves into database
     */
    private  ArrayList parseShippingInfo( String fileName ) throws Exception
    {

        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList shippingInfoList = new ArrayList();
        BufferedReader fileReader = null;

        try
        {
            File shippingInfoFile = new File( fileName );
            if ( shippingInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            System.out.println( "Found " + fileName );
            System.out.println( "Parsing the file for Product Information..." );

            fileReader = new BufferedReader( new FileReader( shippingInfoFile ) );

            String line = null;
            TSMCShippingInfo shippingInfo = null;
            ArrayList errors = new ArrayList();

            fileReader.readLine();  // skip 1st line
            fileReader.readLine();  // skip 2nd line

            while ( ( line = fileReader.readLine() ) != null )
            {

                try
                {
                    shippingInfo = parseShippingInfoLine( line );
                }
                catch ( ScalarException pe )
                {
                    shippingInfo = null;
                    errors.add( pe.getMessage() );
                }

                if ( shippingInfo != null )
                {
                    shippingInfoList.add( shippingInfo );
                }
            }

            fileReader.close();
            fileReader = null;

            System.out.println( "Done parsing.." );

            if ( errors.isEmpty() == false )
            {   // Parser Errors, Send mail to ChipTrac System Administrator
                System.out.println( "\nFound errors... notifying system administrator..." );
                System.out.println( "done\n" );
            }
        }
        finally
        {
            if ( fileReader != null )
            {
                try
                {
                    fileReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return shippingInfoList;
    }
    /**
     * Parses each line into TSMCShippingInfo object
     *
     * @param line to parse
     * @return TSMCShippingInfo parsed data object
     *
     * @throws com.scalar.chiptrack.adaptor.ParserException if there is any problem parsing the line
     */
    private TSMCShippingInfo parseShippingInfoLine( String line ) throws ScalarException
    {

        TSMCShippingInfo shippingInfo = null;

        if ( ( line == null ) || ( line.startsWith( "---" ) ) || ( line.trim().length() < 70 /*min length*/ ) )
        {
            return shippingInfo;
        }

        String[] lineToken = line.split("\"");

        if (lineToken != null && lineToken.length > 1)
        {
            lineToken[1] = lineToken[1].replaceAll(",", "");
        }

        line = "";
        for (int i = 0; i < lineToken.length; i++)
        {
            line = line + lineToken[i];
        }

        try
        {
            String[] token = line.split(",");
            shippingInfo = new TSMCShippingInfo();

            for (int x = 0; x < token.length; x++)
            {
                if (token[x] != null && token[x].trim().length() > 0)
                {
                    switch (x)
                    {
                        case 0:
                            shippingInfo.setInvoiceDate(token[x].trim());
                            break;
                        case 1:
                            shippingInfo.setInvoiceNo(token[x].trim());
                            break;
                        case 2:
                            shippingInfo.setCustomerPO(token[x].trim());
                            break;
                        case 3:
                            shippingInfo.setCustomerProduct(token[x].trim());
                            break;
                        case 4:
                            shippingInfo.setTsmcProduct(token[x].trim());
                            break;
                        case 5:
                            shippingInfo.setUm(token[x].trim());
                            break;
                        case 6:
                            shippingInfo.setCustomerLotID(token[x].trim());
                            break;
                        case 7:
                            shippingInfo.setTsmcLotID(token[x].trim());
                            break;
                        case 8:
                            shippingInfo.setShipQty(token[x].trim());
                            break;
                        case 9:
                            shippingInfo.setComment(token[x].trim());
                            break;
                        case 10:
                            shippingInfo.setWaferQty(token[x].trim());
                            break;
                        case 11:
                            shippingInfo.setDieQty(token[x].trim());
                            break;
                        case 12:
                            shippingInfo.setShipTo(token[x].trim());
                            break;
                        case 13:
                            shippingInfo.setWaferID(token[x].trim());
                            break;
                    }
                }
            }

        }
        catch (Exception e)
        {
            System.out.println( "Exception while parsing Shipping Info: " + e );
            System.out.println( "Line: " + line );
            throw new ScalarException("Exception while parsing Shipping Info: " + e + "\nLine: " + line, e );
        }

        return shippingInfo;
    }
    /**
    *
    * @param shipdataList
    */
   private void getTSMCShipList( ArrayList shipdataList ) throws ScalarException
   {
       TSMCShippingInfo tsmcShipReport = null;
       ShippedLot shippedLot = null;

       String partNumber = null;
       String lotNumber  = null;
       String invoiceNo  = null;
       String shipDate   = null;

       Iterator iterator = shipdataList.iterator();

       while ( iterator.hasNext() )
       {
           tsmcShipReport = ( TSMCShippingInfo ) iterator.next();

           partNumber   = tsmcShipReport.getCustomerProduct();
           lotNumber    = tsmcShipReport.getTsmcLotID();
           invoiceNo    = tsmcShipReport.getInvoiceNo();
           shipDate     = tsmcShipReport.getInvoiceDate();

            if ( tsmcShipReport != null && tsmcShipReport.getTsmcLotID() != null && tsmcShipReport.getTsmcLotID().length() > 0 && tsmcShipReport.getWaferQty() != null
                && tsmcShipReport.getWaferQty().trim().length() > 0  )
            {
                int fabProcessStepId = NewAdaptorDAO.getProcessStepId( partNumber, WIP_TYPE_FAB, WIP_TYPE_FAB );
                String psType        = null;

                if ( fabProcessStepId > 0 )
                {
                    psType  = WIP_TYPE_FAB;
                }
                else
                {
                    psType = "Fab-MemII";
                }

                shippedLot = ( ShippedLot ) m_tsmcShipDataMap.get( lotNumber + partNumber + psType + invoiceNo + shipDate );
                if ( shippedLot == null )
                {
                    shippedLot = new ShippedLot();
                    m_tsmcShipDataMap.put( lotNumber + partNumber + psType + invoiceNo + shipDate, shippedLot );
                }
                int quantity = 0;
                if ( shippedLot.getShipQty() != null )
                {
                   try
                   {
                       quantity = Integer.parseInt( shippedLot.getShipQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                   try
                   {
                       quantity += Integer.parseInt( tsmcShipReport.getWaferQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                }
                else
                {
                   try
                   {
                       quantity = Integer.parseInt( tsmcShipReport.getWaferQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                }
                shippedLot.setLotNumber( lotNumber );
                shippedLot.setPartNumber( partNumber );
                shippedLot.setShipDate( StringUtils.formatDate( shipDate, "MM/dd/yyyy", "MM/dd/yyyy" ) );
                shippedLot.setShipQty( quantity +"" );
                shippedLot.setInvoiceNumber( tsmcShipReport.getInvoiceNo() );
                shippedLot.setCurrentLocation( LOCATION_TYPE_FAB );//PS_TYPE_NAME
                shippedLot.setProcessType( psType );
                shippedLot.setCustomerPO( tsmcShipReport.getCustomerPO() );
                shippedLot.setNextLocation( tsmcShipReport.getShipTo() );
                shippedLot.setVendorName( VENDOR_NAME_TSMC );
                shippedLot.setWaferID( tsmcShipReport.getWaferID() );
				shippedLot.setFabLotNumber( lotNumber );
           }

       }
   }
    /**
     *
     * @param message
     */
    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
    /**
     *
     */
    private void printVersionInfo()
    {
           String info = "\n\n+----------- Running TSMC FAB Data Parser on " + new java.util.Date( System.currentTimeMillis() ) + " -------------+\n" +
                    "\n+---------------------------------------------------------------+\n" +
                    "+                                                                \n" +
                    "+            TSMC FAB Data Interpreter - Beta          \n" +
                    "+                                                                \n" +
                    "+    Copy Right (C) 2008 - ScalarSoft Inc., All rights reserved.  \n" +
                    "+                                                                \n" +
                    "+---------------------------------------------------------------+\n" ;
           System.out.println( info );
           log( info );
    } //end of printVersionInfo
}